package com.neurosky.demo;

import android.content.Context;
import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PorterDuff.Mode;
import android.graphics.PorterDuffXfermode;
import android.util.AttributeSet;
import android.view.View;

public class DrawWaveView extends View {

	private static final String TAG = "DrawWaveView";

	Path mPath = null;
	Paint mPaint = null;

	Bitmap mCacheBitmap = null;
	Canvas mCacheCanvas = null;
	Paint bmpPaint = new Paint();
	private int maxPoint = 0;
	private int currentPoint = 0;
	private int maxValue = 0;
	private int minValue = 0;

	private float mPrevX = 0;
	private float mPrevY = 0;

	private int mBottom = 0;
	private int mHeight = 0;
	private int mLeft = 0;
	private int mWidth = 0;
	
	private float mPixPerHeight = 0;
	private float mPixPerWidth = 0;
	
	public DrawWaveView(Context context)
	{
		super(context);
	}

	public DrawWaveView(Context context, AttributeSet attrs)
	{
		super(context, attrs);
	}
	public void setValue(int maxPoint, int maxValue, int minValue)
	{
		this.maxPoint = maxPoint;
		this.maxValue = maxValue;
		this.minValue = minValue;
	}
	
	public void updateDensity()
	{
		if(isReady())
		{
			mPixPerHeight = (float)mHeight/(maxValue  - minValue);
			mPixPerWidth =  (float)mWidth/maxPoint ;
			clear();
		}
	}
	
	public void initView()
	{
		mBottom = this.getBottom();
		mWidth = this.getWidth();
		mLeft = this.getLeft();
		mHeight = this.getHeight();
		
		mPixPerHeight = (float)mHeight/(maxValue  - minValue);
		mPixPerWidth =  (float)mWidth/maxPoint ;

		mCacheBitmap = Bitmap.createBitmap(mWidth, mHeight, Config.ARGB_8888);
		mCacheCanvas = new Canvas();
		mPath = new Path();
		mCacheCanvas.setBitmap(mCacheBitmap);

		mPaint = new Paint(Paint.DITHER_FLAG);
		mPaint.setColor(Color.BLACK);
		mPaint.setStyle(Paint.Style.STROKE);
		mPaint.setStrokeWidth(2);

		mPaint.setAntiAlias(true);
		mPaint.setDither(true);
		currentPoint =0;
	}
	
	public void clear()
	{
		Paint clearPaint = new Paint();
		clearPaint.setXfermode(new PorterDuffXfermode(Mode.CLEAR));
		mCacheCanvas.drawPaint(clearPaint);
		clearPaint.setXfermode(new PorterDuffXfermode(Mode.SRC));
		currentPoint =0;
		mPath.reset();

		invalidate();
	}
	public boolean isReady()
	{
		return initFlag;
	}
	
	public void updateData(int data)
	{
		if(!initFlag)
		{
			return;
		}
		float y = translateData2Y(data);
		float x = translatePoint2X(currentPoint);

		if(currentPoint == 0){
			mPath.moveTo(x, y);
			currentPoint ++;
			mPrevX = x;
			mPrevY = y;
		}
		else if(currentPoint == maxPoint){
			mCacheCanvas.drawPath(mPath, mPaint);
			currentPoint = 0;
		}
		else
		{
			mPath.quadTo(mPrevX, mPrevX, x, y);
			currentPoint ++;
			mPrevX = x;
			mPrevY = y;
		}
		invalidate();
		if(currentPoint == 0){
			clear();
		}
	}

	private float translateData2Y(int data)
	{
		return (float)mBottom - (data - minValue) *mPixPerHeight ;
	}

	private float translatePoint2X(int point)
	{
		return (float)mLeft + point * mPixPerWidth;
	}
	
    private boolean initFlag = false;
	@Override
	protected void onDraw(Canvas canvas) {

		canvas.drawBitmap(mCacheBitmap, 0, 0, bmpPaint);
		canvas.drawPath(mPath, mPaint);
	}
	@Override
	protected void onConfigurationChanged(Configuration newConfig)
	{
		super.onConfigurationChanged(newConfig);
		initFlag = false;
	}

	@Override
	protected void onLayout(boolean changed, int left, int top, int right, int bottom)
	{
		super.onLayout(changed, left, top, right, bottom);
		 if(!initFlag)
		 {
			 initView();
			 initFlag = true;
		 }
	}
}
